const config = require("./config");
const fs = require("fs");
const Speaker = require("speaker");

let admin = "";
let userLog = "现在进行警长竞选";
let admLog = "";
let god = [];
let gameProcess = config.gameProcess.jxl;
let processIndex = 0;
let havePlayWolf = false;
let confirmSeatObj = {};
let seatObj = {};
let rollObj = {
  1: "0",
  2: "0",
  3: "0",
  4: "0",
  5: "0",
  6: "0",
  7: "0",
  8: "0",
  9: "0",
  10: "0",
  11: "0",
  12: "0",
  13: "0",
};
let learningTarget = "";
let shieldTarget = "";
let deathNum = {};
let isSaveLife = false;
let poisonTarget = "";
let machineWolf = "";
let playerNum = 12;
let doubleDeath1 = "";
let doubleDeath2 = "";

function init() {
  userLog = "现在进行警长竞选";
  admLog = "";
  god = [];
  processIndex = 0;
  havePlayWolf = false;
  confirmSeatObj = {};
  seatObj = {};
  rollObj = {
    1: "0",
    2: "0",
    3: "0",
    4: "0",
    5: "0",
    6: "0",
    7: "0",
    8: "0",
    9: "0",
    10: "0",
    11: "0",
    12: "0",
    13: "0",
  };
  learningTarget = "";
  shieldTarget = "";
  deathNum = {};
  isSaveLife = false;
  poisonTarget = "";
  machineWolf = "";
  doubleDeath1 = "";
  doubleDeath2 = "";
}
function response(data, log) {
  return { data: data, log: log };
}
function play(name) {
  const speaker = new Speaker({
    channels: 2,
    bitDepth: 16,
    sampleRate: 7750,
  });
  fs.createReadStream(`./user_handler/audio/${name}.wav`).pipe(speaker);
}
function process() {
  return gameProcess[processIndex];
}
function nextplay() {
  if (process() != "1" || !havePlayWolf) {
    if (processIndex == 1) {
      play("gameStart");
    } else {
      play("closeEye");
    }
    setTimeout(() => {
      switch (process()) {
        case "-1":
          play("day");
          break;
        case "2":
          play("machineWolf");
          break;
        case "4":
          play("guard");
          break;
        case "1":
          play("wolf");
          havePlayWolf = true;
          break;
        case "3":
          play("witch");
          break;
        case "5":
          play("gun");
          break;
        case "6":
          play("psychic");
          break;
        case "7":
          play("doubleWolf");
          break;
        case "8":
          play("EXprophet");
          break;
        case "9":
          play("child");
          break;
      }
    }, 5000);
  }
}
function nextProcess(num) {
  confirmSeatObj[num] = false;
  rollObj[num] = process();
  processIndex += 1;
  nextplay();
}
function log(log) {
  admLog += `<span>${log}</span><br />`;
}
function playerSeat(req) {
  return seatObj[req.rawHeaders[7]];
}
function isWolf(num) {
  if (rollObj[num] in ["1", "2", "7"]) {
    return true;
  } else {
    return false;
  }
}

exports.get = (req, res) => {
  if (process() != "0" && !playerSeat(req)) {
    res.send(response("-1", "您尚未加入游戏！"));
  } else if (process() != "0" && !confirmSeatObj[playerSeat(req)]) {
    res.send(response("-1", "天黑请闭眼！"));
  } else {
    switch (process()) {
      case "-1":
        if (playerSeat(req) in god) {
          res.send(response(process(), admLog));
        } else {
          res.send(response(process(), userLog));
        }
        break;
      case "0":
        res.send({ data: process(), log: "请选择座位:", playerNum: playerNum });
        break;
      case "2":
        if (learningTarget == "") {
          res.send(response(process(), "请选择你要学习的目标:"));
        } else {
          let tempLog2;
          if (learningTarget == playerSeat(req)) {
            tempLog2 = "您今晚未使用技能";
          } else {
            tempLog2 = `您学到的身份是：${
              config.rollStatus[rollObj[learningTarget]]
            }!`;
            log(
              `机械狼确认习得身份为：${
                config.rollStatus[rollObj[learningTarget]]
              }`
            );
          }
          res.send(response("-1", tempLog2));
          nextProcess(playerSeat(req));
        }
        break;
      case "4":
        res.send(response(process(), "请选择你要守护的对象:"));
        break;
      case "1":
        res.send(response(process(), "请选择你要击杀的对象:"));
        break;
      case "3":
        let list = [];
        let minNum = 1;
        for (let key of Object.keys(deathNum)) {
          if (deathNum[key] > minNum) {
            minNum = deathNum[key];
            list = [];
          }
          if (deathNum[key] == minNum) {
            list.push(key);
          }
        }
        let tempLog3;
        let canSave;
        if (list.length > 0) {
          const randomInt = Math.floor(Math.random() * list.length);
          deathNum = list[randomInt];
          tempLog3 = `今晚死亡的玩家是${deathNum}号，是否使用毒药？是否使用解药？`;
          canSave = deathNum == playerSeat(req) ? false : true;
        } else {
          deathNum = "";
          tempLog3 = "今晚无人死亡，是否使用毒药？";
          canSave = false;
        }
        res.send({
          data: process(),
          log: tempLog3,
          canSave: canSave,
        });
        break;
      case "5":
        const tempLog5 =
          playerSeat(req) == poisonTarget ? "无法开枪" : "可以开枪";
        res.send(response(process(), `你的开枪状态是：${tempLog5}!`));
        log(`猎人${playerSeat(req)}号确认开枪状态为：${tempLog5}`);
        nextProcess(playerSeat(req));
        break;
      case "6":
        res.send(response(process(), "请选择你要查验的对象:"));
        break;
      case "7":
        res.send(response(process(), "请选择你要绑定的对象:"));
        break;
      case "8":
        res.send(response(process(), "请选择你要查验的对象:"));
        break;
      case "9":
        res.send(response(process(), "请选择你的榜样:"));
        break;
    }
  }
};

exports.post = (req, res) => {
  if (process() != "0" && !playerSeat(req)) {
    res.send(response("-1", "您尚未加入游戏！"));
  } else if (process() != "0" && !confirmSeatObj[playerSeat(req)]) {
    res.send(response("-1", "天黑请闭眼！"));
  } else {
    switch (process()) {
      case "0":
        if (playerSeat(req)) {
          confirmSeatObj[playerSeat(req)] = false;
          delete seatObj[req.rawHeaders[7]];
        }
        if (req.query.seat == "") {
          res.send(response(process(), "您未选择或已取消座位"));
        } else {
          if (!confirmSeatObj[req.query.seat]) {
            seatObj[req.rawHeaders[7]] = req.query.seat;
            confirmSeatObj[req.query.seat] = true;
            console.log(
              `${req.query.seat}号玩家第${Object.keys(seatObj).length}位入座`
            );
            res.send(response(process(), `${req.query.seat}号玩家，欢迎！`));
          } else {
            res.send(
              response(process(), `${req.query.seat}号已被占，请确认情况`)
            );
          }
        }
        break;
      case "2":
        learningTarget =
          req.query.seat == "" ? playerSeat(req) : req.query.seat;
        const tempLog2 =
          learningTarget == playerSeat(req)
            ? "您未使用学习技能,"
            : `您的学习目标是${req.query.seat}号,`;
        machineWolf = playerSeat(req);
        res.send(
          response(process(), `${tempLog2}请等通灵师行动结束后再确认身份！`)
        );
        if (req.query.seat == "") {
          log(`机械狼${playerSeat(req)}号玩家未使用技能`);
        } else {
          log(`机械狼${playerSeat(req)}号玩家选择学习${req.query.seat}号`);
        }
        nextProcess(playerSeat(req));
        break;
      case "4":
        shieldTarget = req.query.seat;
        const tempLog4 =
          req.query.seat == ""
            ? "您今晚空守"
            : `您已守护${req.query.seat}号玩家`;
        res.send(response(process(), tempLog4));
        if (req.query.seat == "") {
          log(`守卫${playerSeat(req)}号玩家选择空守`);
        } else {
          log(`守卫${playerSeat(req)}号玩家选择守护${req.query.seat}号`);
        }
        nextProcess(playerSeat(req));
        break;
      case "1":
        if (req.query.seat == "") {
          res.send(response(process(), "您今晚未选择击杀"));
          log(`狼人${playerSeat(req)}号玩家选择空刀`);
        } else {
          if (!deathNum[req.query.seat]) {
            deathNum[req.query.seat] = 0;
          }
          deathNum[req.query.seat] += 1;
          res.send(response(process(), `您今晚选择击杀${req.query.seat}号!`));
          log(`狼人${playerSeat(req)}号玩家选择击杀${req.query.seat}号`);
        }
        nextProcess(playerSeat(req));
        break;
      case "3":
        if (req.query.param1 == "0") {
          res.send(response(process(), "您今晚未使用技能"));
          log(`女巫${playerSeat(req)}号玩家未发动技能`);
        } else if (req.query.param1 == "1" && playerSeat(req) != deathNum) {
          isSaveLife = true;
          res.send(response(process(), `您已对${deathNum}号玩家使用解药!`));
          log(`女巫${playerSeat(req)}号玩家选择解救${deathNum}号玩家`);
        } else if (req.query.param1 == "2") {
          if (req.query.seat == "") {
            res.send(response(process(), "您今晚未使用技能"));
            log(`女巫${playerSeat(req)}号玩家未发动技能`);
          } else {
            poisonTarget = req.query.seat;
            res.send(
              response(process(), `您已对${req.query.seat}号玩家使用毒药!`)
            );
            log(`女巫${playerSeat(req)}号玩家选择毒杀${req.query.seat}号玩家`);
          }
        } else {
          res.send(response(process(), "您不能对自己使用解药!技能不生效"));
          log(`女巫${playerSeat(req)}号玩家未发动技能`);
        }
        nextProcess(playerSeat(req));
        break;
      case "6":
        if (req.query.seat == "") {
          res.send(response(process(), "您今晚未使用技能"));
          log(`通灵师${playerSeat(req)}号玩家未发动技能`);
        } else if (req.query.seat == playerSeat(req)) {
          res.send(
            response(process(), `${req.query.seat}号玩家的身份是：通灵师`)
          );
          log(`通灵师${playerSeat(req)}号玩家查验自己为通灵师`);
        } else {
          let roll;
          if (rollObj[req.query.seat] == "2") {
            roll = config.rollStatus[rollObj[learningTarget]];
          } else {
            roll = config.rollStatus[rollObj[req.query.seat]];
          }
          res.send(
            response(process(), `${req.query.seat}号玩家的身份是：${roll}`)
          );
          log(
            `通灵师${playerSeat(req)}号玩家查验${req.query.seat}号玩家为${roll}`
          );
        }
        confirmSeatObj[machineWolf] = true;
        nextProcess(playerSeat(req));
        break;
      case "7":
        if (req.query.seat.length == 0) {
          res.send(response(process(), "您今晚未使用技能"));
          log(`寻香魅影${playerSeat(req)}号玩家未发动技能`);
        } else if (
          req.query.seat.length == 1 &&
          req.query.seat == playerSeat(req)
        ) {
          res.send(response(process(), "您今晚未使用技能"));
          log(`寻香魅影${playerSeat(req)}号玩家未发动技能`);
        } else {
          if (req.query.seat.length == 1) {
            doubleDeath1 = playerSeat(req);
            doubleDeath2 = req.query.seat;
          } else {
            doubleDeath1 = req.query.seat[0];
            doubleDeath2 = req.query.seat[2];
          }
          res.send(
            response(
              process(),
              `您已绑定${doubleDeath1}号和${doubleDeath2}号玩家`
            )
          );
          log(
            `寻香魅影${playerSeat(
              req
            )}号玩家发动技能绑定${doubleDeath1}号和${doubleDeath2}号玩家`
          );
        }
        nextProcess(playerSeat(req));
        break;
      case "8":
        if (req.query.seat.length == 0) {
          res.send(response(process(), "您今晚未使用技能"));
          log(`觉醒预言家${playerSeat(req)}号玩家未发动技能`);
        } else if (req.query.seat.length == 1) {
          if (req.query.seat == playerSeat(req)) {
            res.send(response(process(), "您今晚未使用技能"));
            log(`觉醒预言家${playerSeat(req)}号玩家未发动技能`);
          } else {
            const doubleResult =
              isWolf(playerSeat(req)) || isWolf(req.query.seat);
            const tempLog8 = doubleResult ? "疑似狼人" : "金水";
            res.send(
              response(
                process(),
                `您查验${playerSeat(req)}号和${
                  req.query.seat
                }号玩家为${tempLog8}`
              )
            );
            log(
              `觉醒预言家${playerSeat(req)}号玩家查验${req.query.seat}号和${
                req.query.seat
              }号为${tempLog8}`
            );
          }
        } else {
          const doubleResult =
            isWolf(req.query.seat[0]) && isWolf(req.query.seat[2]);
          const tempLog8 = doubleResult ? "疑似狼人" : "金水";
          res.send(
            response(
              process(),
              `您查验${req.query.seat[0]}号和${req.query.seat[2]}号玩家为${tempLog8}`
            )
          );
          log(
            `觉醒预言家${playerSeat(req)}号玩家查验${req.query.seat[0]}号和${
              req.query.seat[2]
            }号为${tempLog8}`
          );
        }
        nextProcess(playerSeat(req));
        break;
      case 9:
        let father = req.query.seat;
        while (father == "" || father == playerSeat(req)) {
          father = Math.ceil(Math.random() * playerNum);
        }
        res.send(response(process(), `您已选择${father}号玩家为榜样`));
        log(`混血儿${playerSeat(req)}号玩家选择${father}号玩家为榜样`);
        nextProcess(playerSeat(req));
        break;
    }
  }
};

exports.home = (req, res) => {
  admin = req.rawHeaders[13];
  res.sendFile(__dirname + "/adm_page/" + "admin.html");
};

exports.start = (req, res) => {
  if (req.rawHeaders[13] == admin) {
    console.log("gamestart");
    if (processIndex == 0) {
      processIndex = 1;
    }
    res.sendFile(__dirname + "/adm_page/" + "admin.html");
    nextplay();
  }
};

exports.situation = (req, res) => {
  if (req.rawHeaders[13] == admin) {
    let deathList = new Map();
    if (isSaveLife) {
      if (deathNum == shieldTarget) {
        deathList.set(deathNum, true);
      }
    } else {
      if (poisonTarget == "") {
        if (deathNum != shieldTarget) {
          deathList.set(deathNum, true);
        }
      } else {
        if (deathNum == shieldTarget) {
          deathList.set(poisonTarget, true);
        } else {
          deathList.set(deathNum, true);
          deathList.set(poisonTarget, true);
        }
      }
      if (deathList.get(doubleDeath1) || deathList.get(doubleDeath2)) {
        deathList.set(doubleDeath1, true);
        deathList.set(doubleDeath2, true);
      }
      let tempUserLog = "昨夜死亡的玩家是：";
      for (let key of deathList.keys()) {
        tempUserLog += `${key}号 `;
      }
      userLog = tempUserLog;
      log(userLog);
    }
    res.sendFile(__dirname + "/adm_page/" + "admin.html");
  }
};

exports.god = (req, res) => {
  if (req.rawHeaders[13] == admin) {
    god.push(req.query.seat);
    log(`${god}号玩家成为法官`);
    res.sendFile(__dirname + "/adm_page/" + "admin.html");
  }
};

exports.type = (req, res) => {
  if (req.rawHeaders[13] == admin) {
    init();
    gameProcess = config.gameProcess[req.query.type];
    playerNum = config.playerNum[req.query.type];
    console.log(`游戏重置，版型为${req.query.type}`);
    res.sendFile(__dirname + "/adm_page/" + "admin.html");
  }
};
